package com.material.vtool.service.impl;

import com.github.pagehelper.PageHelper;
import com.material.vtool.entity.BMaterialTypeInfoEntity;
import com.material.vtool.entity.combinedEntity.CombinedCommonArticleEntity;
import com.material.vtool.entity.combinedEntity.CombinedRecommendArticleEntity;
import com.material.vtool.entity.combinedEntity.HotSearch;
import com.material.vtool.entity.respEntity.ReturnCode;
import com.material.vtool.exception.ServiceException;
import com.material.vtool.mapper.MaterialInfoMapper;
import com.material.vtool.mapper.UserInfoMapper;
import com.material.vtool.service.MaterialInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class MaterialInfoServiceImpl implements MaterialInfoService {
    private final ReentrantLock materialCollectLock = new ReentrantLock();

    private final ReentrantLock userCollectLock = new ReentrantLock();

    @Autowired
    private MaterialInfoMapper materialInfoMapper;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Override
    public List<CombinedRecommendArticleEntity> getRecommendArticleByTime(Integer pageNum, Integer pageSize, List<Integer> materialTypeIds) {
        PageHelper.startPage(pageNum, pageSize);
        return materialInfoMapper.getRecommendArticleByTime(materialTypeIds);
    }

    @Override
    public int getRecommendArticleByTimeTotal(List<Integer> materialTypeIds) {
        Integer total = materialInfoMapper.getRecommendArticleByTimeTotal(materialTypeIds);
        return total == null ? 0 : total.intValue();
    }

    @Override
    public List<CombinedRecommendArticleEntity> getRecommendArticle(List<Integer> materialTypeIds) {
        return materialInfoMapper.getRecommendArticle(materialTypeIds);
    }

    @Override
    public List<CombinedCommonArticleEntity> getArticleByMaterialTypeId(Integer pageNum, Integer pageSize, Integer materialTypeId) {
        PageHelper.startPage(pageNum, pageSize);
        return materialInfoMapper.getArticleByMaterialTypeId(materialTypeId);
    }

    @Override
    public int getArticleByMaterialTypeIdTotal(Integer materialTypeId) {
        Integer total = materialInfoMapper.getArticleByMaterialTypeIdTotal(materialTypeId);
        return total == null ? 0 : total.intValue();
    }

    @Override
    public List<HotSearch> getHotSearch(String miniCode) {
        return materialInfoMapper.getHotSearch(miniCode);
    }

    @Override
    public List<CombinedCommonArticleEntity> searchMaterialByKey(Integer pageNum, Integer pageSize, String miniCode, String key) {
        PageHelper.startPage(pageNum, pageSize);
        return materialInfoMapper.searchMaterialByKey(miniCode, key);
    }

    @Override
    public int searchMaterialByKeyTotal(String miniCode, String key) {
        Integer total = materialInfoMapper.searchMaterialByKeyTotal(miniCode, key);
        return total == null ? 0 : total.intValue();
    }

    @Override
    public BMaterialTypeInfoEntity getMaterialTypeByMaterialId(Integer materialId) {
        return materialInfoMapper.getMaterialTypeByMaterialId(materialId);
    }

    @Override
    @Transactional
    @Async
    public void AsyncTaskSaveMaterialCollectInfo(Integer userId, Integer materialId) {
        // 素材收藏数量 + 1
        try {
            materialCollectLock.lock();
            Integer affectedCount1 = materialInfoMapper.increaseCollectCount(materialId);
            if (affectedCount1 == null || affectedCount1.intValue() == 0) throw new ServiceException("更新文章收藏次数失败", ReturnCode.SERVER_ERROR);
        } finally {
            materialCollectLock.unlock();
        }

        // 用户收藏数量 + 1
        try {
            userCollectLock.lock();
            Integer affectedCount2 = userInfoMapper.increaseCollectCount(userId);
            if (affectedCount2 == null || affectedCount2.intValue() == 0) throw new ServiceException("更新用户收藏次数失败", ReturnCode.SERVER_ERROR);
        } finally {
            userCollectLock.unlock();
        }
    }

    @Override
    public CombinedCommonArticleEntity getMaterialInfoById(Integer materialId) {
        return materialInfoMapper.getMaterialInfoById(materialId);
    }
}
